﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataAccessLayer;
using PurchaseOrderExtra;
using System.Transactions;

namespace BusinessLogicLayer
{
    public class ApprovePurchaseOrderControl
    {
        SupplierRepository supplierRepo;
        UserRepository userRepo;
        EmployeeRepository employeeRepo;
        PurchaseOrderRepository purchaseOrderRepo;
        PurchaseOrderDetailRepository purchaseOrderDetailRepo;
        SupplierDetailRepository supplierDetailRepo;

        EmailNotificationControl emailNotificationControl;

        public ApprovePurchaseOrderControl()
        {
            supplierRepo = new SupplierRepository();
            userRepo = new UserRepository();
            employeeRepo = new EmployeeRepository();
            purchaseOrderRepo = new PurchaseOrderRepository();
            purchaseOrderDetailRepo = new PurchaseOrderDetailRepository();
            supplierDetailRepo = new SupplierDetailRepository();
            emailNotificationControl = new EmailNotificationControl();
        }

        public User GetUserByUsername(string username)
        {
            return userRepo.GetUserByUsername(username);
        }

        public Employee GetEmployeeByUserId(int userId)
        {
            return employeeRepo.GetEmployeeByUserId(userId);
        }

        public List<Supplier> DisplayAllSupplier()
        {
            List<Supplier> list = new List<Supplier>();
            Supplier supplier = new Supplier();
            supplier.SupplierID = "ALL";
            supplier.SupplierName = "All Suppliers";
            list.Add(supplier);
            List<Supplier> supList = supplierRepo.GetAllSupplier();
            foreach (Supplier sup in supList)
            {
                list.Add(sup);
            }
            return list;
        }

        public List<Employee> DisplayAllStoreClerk()
        {
            List<Employee> list = new List<Employee>();
            Employee employee = new Employee();
            employee.EmployeeID = 0;
            employee.EmployeeName = "All Store Clerks";
            list.Add(employee);
            List<Employee> empList = employeeRepo.GetEmployeeByRoleName("Store Clerk");
            foreach (Employee emp in empList)
            {
                list.Add(emp);
            }
            return list;
        }

        public List<PurchaseOrderListDisplay> GetAllPurchaseOrder()
        {
            string status = "Pending";
            List<PurchaseOrder> poList = new List<PurchaseOrder>();
            poList = purchaseOrderRepo.GetPurchaseOrderByStatus(status);
            List<PurchaseOrderListDisplay> list = new List<PurchaseOrderListDisplay>();
            foreach (PurchaseOrder po in poList)
            {
                PurchaseOrderListDisplay poListDisplay = new PurchaseOrderListDisplay();
                poListDisplay.POId = po.POID;
                poListDisplay.SupplierName = po.Supplier.SupplierName;
                poListDisplay.RequestedBy = po.Employee1.EmployeeName;
                poListDisplay.ExpectedDate = po.ExpectedDeliveryDate.Value.ToShortDateString();
                list.Add(poListDisplay);
            }
            return list;
        }

        public List<PurchaseOrderListDisplay> GetPurchaseOrderBySupplierId(string supplierId)
        {
            string status = "Pending";
            List<PurchaseOrder> poList = new List<PurchaseOrder>();
            poList = purchaseOrderRepo.GetPurchaseOrderBySupplierIdAndStatus(supplierId, status);
            List<PurchaseOrderListDisplay> list = new List<PurchaseOrderListDisplay>();
            foreach (PurchaseOrder po in poList)
            {
                PurchaseOrderListDisplay poListDisplay = new PurchaseOrderListDisplay();
                poListDisplay.POId = po.POID;
                poListDisplay.SupplierName = po.Supplier.SupplierName;
                poListDisplay.RequestedBy = po.Employee1.EmployeeName;
                poListDisplay.ExpectedDate = po.ExpectedDeliveryDate.Value.ToShortDateString();
                list.Add(poListDisplay);
            }
            return list;
        }

        public List<PurchaseOrderListDisplay> GetPurchaseOrderByRequestedBy(int requestedBy)
        {
            string status = "Pending";
            List<PurchaseOrder> poList = new List<PurchaseOrder>();
            poList = purchaseOrderRepo.GetPurchaseOrderByRequestedByAndStatus(requestedBy, status);
            List<PurchaseOrderListDisplay> list = new List<PurchaseOrderListDisplay>();
            foreach (PurchaseOrder po in poList)
            {
                PurchaseOrderListDisplay poListDisplay = new PurchaseOrderListDisplay();
                poListDisplay.POId = po.POID;
                poListDisplay.SupplierName = po.Supplier.SupplierName;
                poListDisplay.RequestedBy = po.Employee1.EmployeeName;
                poListDisplay.ExpectedDate = po.ExpectedDeliveryDate.Value.ToShortDateString();
                list.Add(poListDisplay);
            }
            return list;
        }

        public List<PurchaseOrderListDisplay> GetPurchaseOrderBySupplierIdAndRequestedBy(string supplierId, int requestedBy)
        {
            string status = "Pending";
            List<PurchaseOrder> poList = new List<PurchaseOrder>();
            poList = purchaseOrderRepo.GetPurchaseOrderBySupplierIdAndRequestedByAndStatus(supplierId, requestedBy, status);
            List<PurchaseOrderListDisplay> list = new List<PurchaseOrderListDisplay>();
            foreach (PurchaseOrder po in poList)
            {
                PurchaseOrderListDisplay poListDisplay = new PurchaseOrderListDisplay();
                poListDisplay.POId = po.POID;
                poListDisplay.SupplierName = po.Supplier.SupplierName;
                poListDisplay.RequestedBy = po.Employee1.EmployeeName;
                poListDisplay.ExpectedDate = po.ExpectedDeliveryDate.Value.ToShortDateString();
                list.Add(poListDisplay);
            }
            return list;
        }

        public string ViewPurchaseOrderDetail()
        {
            string redirectURL = "/ApprovePurchaseOrder.aspx";
            return redirectURL;
        }

        public PurchaseOrder GetPurchaseOrderByPOId(int poId)
        {
            return purchaseOrderRepo.GetPurchaseOrderByPOId(poId);
        }

        public List<PurchaseOrderDisplay> GetPurchaseOrderDisplay(int poId)
        {
            List<PurchaseOrderDetail> poDetailList = new List<PurchaseOrderDetail>();
            poDetailList = purchaseOrderDetailRepo.GetPurchaseOrderDetailByPOId(poId);

            List<PurchaseOrderDisplay> list = new List<PurchaseOrderDisplay>();
            foreach (PurchaseOrderDetail poDetail in poDetailList)
            {
                string supplierId = poDetail.PurchaseOrder.SupplierID;
                string itemCode = poDetail.ItemCode;
                int quantity = (int)poDetail.POQty;
                decimal unitPrice = (decimal)supplierDetailRepo.GetSupplierDetailBySupplierIdAndItemCode(supplierId, itemCode).Price;

                PurchaseOrderDisplay poDisplay = new PurchaseOrderDisplay();
                poDisplay.PODetailId = poDetail.PODetailID;
                poDisplay.ItemCode = itemCode;
                poDisplay.ItemName = poDetail.Stationery.ItemName;
                poDisplay.Quantity = quantity;
                poDisplay.UnitOfMeasurement = poDetail.Stationery.UOM;
                poDisplay.UnitPrice = unitPrice;
                poDisplay.Amount = CalculateAmount(quantity, unitPrice);
                list.Add(poDisplay);
            }
            return list;
        }

        private decimal CalculateAmount(int quantity, decimal price)
        {
            return (quantity * price);
        }

        public string RedirectToPurchaseOrderListForApproval()
        {
            string redirectURL = "/ApprovePurchaseOrderList.aspx";
            return redirectURL;
        }

        public void UpdateApprovePurchaseOrder(User user, int poId, string reason)
        {
            try
            {        
                PurchaseOrder purchaseOrder = new PurchaseOrder();
                purchaseOrder = purchaseOrderRepo.GetPurchaseOrderByPOId(poId);
                purchaseOrder.ApprovalBy = employeeRepo.GetEmployeeByUserId(user.UserID).EmployeeID;
                purchaseOrder.ApprovalDate = DateTime.Now;
                purchaseOrder.Status = "Approved";
                purchaseOrder.Reason = reason;
                purchaseOrderRepo.UpdatePurchaseOrder(purchaseOrder);
                EmailToSupplier(poId);
            }
            catch (Exception ex)
            {
            }
        }

        public void UpdateRejectPurchaseOrder(User user, int poId, string reason)
        {
            try
            {
                PurchaseOrder purchaseOrder = new PurchaseOrder();
                purchaseOrder = purchaseOrderRepo.GetPurchaseOrderByPOId(poId);
                purchaseOrder.ApprovalBy = employeeRepo.GetEmployeeByUserId(user.UserID).EmployeeID;
                purchaseOrder.ApprovalDate = DateTime.Now;
                purchaseOrder.Status = "Rejected";
                purchaseOrder.Reason = reason;
                purchaseOrderRepo.UpdatePurchaseOrder(purchaseOrder);
                EmailToClerk(poId);
            }
            catch (Exception ex)
            {
            }
        }

        public string RedirectToPurchaseOrderConfirmation()
        {
            string redirectURL = "/PurchaseOrderConfirmation.aspx";
            return redirectURL;
        }

        // Format email to supplier
        private void EmailToSupplier(int poId)
        {
            PurchaseOrder purchaseOrder = purchaseOrderRepo.GetPurchaseOrderByPOId(poId);
            Supplier supplier = purchaseOrder.Supplier;
            string supplierEmail = supplier.Email;
            string supplierName = supplier.SupplierName;
            string supplierAddress = supplier.Address;
            string supplierContactPerson = supplier.ContactName;

            Employee manager = purchaseOrder.Employee2;
            string fromEmail = manager.Email;
            string toEmail = supplierEmail;
            string subject = "Logic University Stationery Purchase Order (Purchase Order No " + poId + ")";
            string body = "<h1>Logic University</h1>"+
                          "<h3>Stationery Purchase Order</h3>" + "<br/>" +
                          "<b>Purchase Order No: </b>" + poId + "<br/><br/>" +
                          "<table>" +
                          "<tr><td><b>Supplier: </b></td><td>" + supplierName + "</td></tr>" +
                          "<tr><td>&nbsp;</td><td>" + supplierAddress + "</td></tr>" +
                          "<tr><td>&nbsp;</td><td>" + supplierContactPerson + "</td></tr>" +
                          "</table>" +
                          "<br/>" +
                          "<table>" +
                          "<tr><td><b>Deliver to: </b></td><td>Logic University Stationery Store</td></tr>" +
                          "<tr><td>&nbsp;</td><td>123 Kent Ridge Drive Singapore 660123</td></tr>" +
                          "<tr><td><b>Attn: </b></td><td>" + purchaseOrder.Employee.EmployeeName +"</td></tr>" +
                          "</table>"  +
                          "<br/><br/>" +
                          "Dear " + supplierContactPerson + "," + "<br/><br/>" +
                          "Please supply the following items by " + purchaseOrder.ExpectedDeliveryDate.Value.ToShortDateString() + "." + "<br/><br/>" + 
                          "<table>" +
                          "<tr>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Item Number</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Item Name</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Quantity</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Unit Price (S$)</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Amount (S$)</b></td>" +
                          "</tr>";

            decimal total = 0;
            List<PurchaseOrderDisplay> poDisplayList = GetPurchaseOrderDisplay(poId);
            foreach (PurchaseOrderDisplay poDisplay in poDisplayList)
            {
                string rowInfo = "<tr>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.ItemCode + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.ItemName + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.Quantity + " " + poDisplay.UnitOfMeasurement + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.UnitPrice + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.Amount + "</td>" +
                                 "</tr>";
                body = body + rowInfo;
                total = total + poDisplay.Amount;
            }

            body = body +
                   "</table>" + 
                   "<br/>" +
                   "<b>Total (S$): </b>" + total +"<br/><br/><br/>" +
                   "Thank you." + "<br/><br/>" +
                   "Yours sincerely," + "<br/>" +
                   "Logic University Stationery Store"; 

            emailNotificationControl.sendHtmlEmail(fromEmail, toEmail, subject, body);
        }

        // Format email to clerk
        private void EmailToClerk(int poId)
        {
            PurchaseOrder purchaseOrder = purchaseOrderRepo.GetPurchaseOrderByPOId(poId);
            Employee clerk = purchaseOrder.Employee1;
            string clerkName = clerk.EmployeeName;
            string clerkEmail = clerk.Email;
            Employee manager = purchaseOrder.Employee2;
            string managerName = manager.EmployeeName;

            string fromEmail = manager.Email;
            string toEmail = clerkEmail;
            string subject = "Purchase Order Rejected (Purchase Order No " + poId + ")";
            string body = "Dear " + clerkName + "," + "<br/><br/>" +
                          "The following purchase order (Purchase Order No " + poId +") has been rejected." + "<br/><br/>" + 
                          "<table>" +
                          "<tr>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Item Name</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Quantity</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Unit Price (S$)</b></td>" +
                          "<td style='border:1px solid black;padding:5px;'><b>Amount (S$)</b></td>" +
                          "</tr>";

            decimal total = 0;
            List<PurchaseOrderDisplay> poDisplayList = GetPurchaseOrderDisplay(poId);
            foreach (PurchaseOrderDisplay poDisplay in poDisplayList)
            {
                string rowInfo = "<tr>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.ItemName + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.Quantity + " " + poDisplay.UnitOfMeasurement + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.UnitPrice + "</td>" +
                                 "<td style='border:1px solid black;padding:5px;'>" + poDisplay.Amount + "</td>" +
                                 "</tr>";
                body = body + rowInfo;
                total = total + poDisplay.Amount;
            } 

            body = body +
                   "</table>" +
                   "<br/>" +
                   "<b>Total (S$): </b>" + total + "<br/><br/>" +
                   "<b>Reason: </b>" + purchaseOrder.Reason + "<br/><br/><br/>" +
                   "Thank you." + "<br/><br/>" +
                   "Yours sincerely," + "<br/>" +
                   managerName;
            emailNotificationControl.sendHtmlEmail(fromEmail, toEmail, subject, body);
        }

    }
}
